/*
 * @Author: Bboy大蛇 2951845438@qq.com
 * @Date: 2024-08-28 11:36:48
 * @LastEditors: Bboy大蛇 2951845438@qq.com
 * @LastEditTime: 2024-10-15 17:03:23
 * @FilePath: \cocos_frame\assets\script\src\Basic\UI\PanelBase.ts
 */
import { _decorator, Animation, Asset, Component, EventTouch, Node, v3 } from 'cc';
import { BaseEventType, LayerType, RepelType } from '../Config/BaseEnum';
import { CallBackHandler } from '../Model/PoolObj/CallBackHandler';
import { LayerIndexType } from '../../Game/Config/GameEnum';
import type { PanelModel } from './PanelModel';
import { StringUtil } from '../../Util/StringUtil';
import { EventManager } from '../Manager/EventManager';
/*eslint-disable*/
const { property, disallowMultiple, ccclass } = _decorator;

/** 界面基类 */
@ccclass('PanelBase')
@disallowMultiple(true)
export abstract class PanelBase extends Component {
  @property([Asset])
  resources: Asset[] = [];

  @property(Node)
  private moveNode: Node;

  @property(Animation)
  private frameAnim: Animation;

  @property({
    visible() {
      return this.frameAnim != null;
    },
  })
  openPlay: string = '';

  @property({
    visible() {
      return this.frameAnim != null;
    },
  })
  closePlay: string = '';
  /** 可变的打开回调 */
  openCallback: CallBackHandler | null = null;
  /** 可变的关闭回调 */
  closeCallback: CallBackHandler | null = null;

  /** 界面层级 */
  abstract readonly panelLayer:
    | LayerType.MainLayer
    | LayerType.MenuLayer
    | LayerType.PanelLayer
    | LayerType.DialogLayer
    // | LayerType.topLayer
    | LayerType.TipsLayer
    | LayerType.GuideLayer
    | LayerType.LoadingLayer;
  /** 界面互斥类型 可以重写，不能修改 */
  readonly panelRepelType: RepelType = RepelType.Self;
  /** 界面索引 可以重写，不能修改*/
  readonly panelIndex: LayerIndexType = LayerIndexType.DEFAULT;
  /** 界面是否自动释放 */
  autoRelease: boolean = true;
  /** 界面数据管理类 */
  panelModel?: PanelModel;
  /** 界面蒙版透明度 */
  @property({
    serializable: false,
    tooltip: '界面蒙版透明度',
  })
  blackMask: number = 0.75;
  @property({
    serializable: false,
    tooltip: '是否点击背景关闭',
  })
  clickBackClose: boolean = true;
  @property({ tooltip: '点击ui之外是否穿透' })
  isPierce: boolean = false;

  /** 单例界面唯一标识 */
  get panelName(): string {
    const temp = this.name;
    return StringUtil.extractString(temp, '<>');
  }

  isReady: boolean = false;
  /** 准备完成开始动画 */
  protected override onEnable() {
    if (!this.isReady) {
      this.isReady = true;
      if (this.moveNode) {
        this.moveNode.on(Node.EventType.TOUCH_MOVE, this._onTouchMove, this);
        this.moveNode.on(Node.EventType.TOUCH_START, this._onTouchBegan, this);
        // this.moveNode.on(NodeEventType.TOUCH_END, this._onTouchEnded, this);
        // this.moveNode.on(NodeEventType.TOUCH_CANCEL, this._onTouchEnded, this);
      }
    }
    this.onRender();
    this.onOpen();
  }

  private onOpen(): void {
    if (this.frameAnim != null && this.openPlay != '') {
      this.frameAnim.play(this.openPlay);
      return;
    }
    this.openComplete();
  }

  private openComplete() {
    this.openCallback?.execute(this);
    this.openCallback = null;
    this.onReady();
  }

  private _onCloseCallback: CallBackHandler | null = null;
  /** 直接调用并不能关闭界面，只是会播放关闭动画 */
  onClose(callback?: CallBackHandler) {
    this.onCloseReady();
    this._onCloseCallback = callback;
    if (this.frameAnim != null && this.closePlay != '') {
      this.frameAnim.play(this.closePlay);
      return;
    }
    this.closeComplete();
  }

  private closeComplete() {
    this._onCloseCallback?.execute(this);
    this._onCloseCallback = null;
    this.closeCallback?.execute(this);
    this.closeCallback = null;
    this.node.removeFromParent();
    this.close();
  }

  clickClose(event?: TouchEvent, val?: string) {
    EventManager.Ins().emit(BaseEventType.GAME_CLOSE_PANEL, this.panelName);
  }

  /** 关闭自己，适用于不受LayerManager控制的页面 */
  closeSelf(event?: TouchEvent, val?: string) {
    if (val == 'release') {
      this.onClose(
        CallBackHandler.pop(() => {
          this.panelModel?.releaseDynamicRes();
          this.node.destroy();
        }, this)
      );
    } else {
      this.onClose(
        CallBackHandler.pop(() => {
          this.node.removeFromParent();
        }, this)
      );
    }
  }

  private _onTouchBegan(event: EventTouch) {
    const pos = event.getUIDelta();
    this.node.translate(v3(pos.x, pos.y));
  }

  private _onTouchMove(event: EventTouch) {
    const pos = event.getUIDelta();
    this.node.translate(v3(pos.x, pos.y));
  }

  /** 替代onEnable，节点添加到场景是调用 */
  onRender() {}
  /** onEnable之后调用，如果设置界面动画，则在动画之后调用 */
  onReady() {}
  /** 界面在移出场景前，如果设置界面动画，则在动画之后调用 */
  onCloseReady() {}
  /** 界面在移出场景前，如果设置界面动画，则在动画之后调用 */
  close() {}
}
